7.1 错误处理

很多时候我们都会遇到错误的情况,比如类型转换、请求第三方、连接数据库等出现错误。

这时候就需要我们对异常进行进一步的处理,避免影响正常的业务逻辑。

比如在类型转换时,从string转换为int,转换出错了。

那么这时候我们就不能继续进行下一步的业务逻辑处理,因为这可能会导致我们的业务错误。

本节代码存放目录为 lesson19

错误接收方式

Go语言中,除去一些自定义错误的场景,错误处理一般使用的都是error包。如下代码所示:

a := "1234t"
num, err := strconv.ParseInt(a, 10, 64)
if err != nil {
    fmt.Printf("转换出错: err-> %v\n", err)
    return
}
fmt.Printf("转换成功, num-> %d\n", num)

在上面的代码中,我们定义了一个字符串变量a,之后我们通过strconv.ParseInt将字符串转换为int64类型的num

同时我们使用err接收了转换产生的错误,通过查看strconv.ParseInt的源码,我们可以看到他是这样的:

func ParseInt(s string, base int, bitSize int) (i int64, err error) {}

返回了一个转换得到的值int64,同时返回了一个error错误。

所以我们在接收的时候,num就对应ierr就对应error

执行上面的代码,结果如下所示:

转换出错: err-> strconv.ParseInt: parsing "1234t": invalid syntax

通过输出我们可以看到转换过程中出现了错误,我们通过占位符%v将错误信息进行了输出。

同时我们还可以如下这样,将error类型转换得到字符串错误信息。

fmt.Printf("转换出错: err-> %v, str-> %s\n", err, err.Error())

自定义错误

在一些场景中,我们不会使用到官方的错误信息,而是需要我们进行一些自定义错误。

比如,我们定义了一个函数,如果输入的数字小于了10,那么我们需要返回错误:数字太小

如下代码所示:

func checkNum(num int) (bool, error) {
    if num < 10 {
        return false, fmt.Errorf("数字太小, 输入数字为: %d", num)
    }
    return true, nil
}

在上面的代码中,我们通过fmt.Errorf组装了一个错误信息进行返回,占位符的使用与我们之前章节讲到的是一致的。

我们可以这样调用:

ok, err := checkNum(9)
if err != nil {
    fmt.Printf("检查错误信息: %v\n", err)
}
fmt.Printf("检查结果: %v\n", ok)

执行输出如下所示:

检查错误信息: 数字太小, 输入数字为: 9
检查结果: false

除了使用fmt.Errorf之外,我们还可以使用errors.New来实现,如下所示:

if num > 15 {
    return false, errors.New(fmt.Sprintf("数字太大, 输入数字为: %d", num))
}

调用方式如下所示:

ok1, err1 := checkNum(17)
if err1 != nil {
    fmt.Printf("检查错误信息1: %v\n", err1)
}
fmt.Printf("检查结果1: %v\n", ok1)

在我们不想要接收ok值的时候,我们还可以进行简写,如下所示:

if _, err2 := checkNum(18); err != nil {
    fmt.Printf("检查错误信息2: %v\n", err2)
}

除了上面这些处理方式,我们还可以有其他的定义。

我们在之前学习到了结构体,我们就可以结合结构体来做,比如我们进行如下定义:

type CheckErr struct {
    Code int
    Msg  string
}

我们新建一个函数进行使用测试,如下所示:

func checkNum1(num int) (bool, *CheckErr) {
    if num < 10 {
        return false, &CheckErr{
            Code: 1,
            Msg:  fmt.Sprintf("数字太小了, 输入的数字是: %d", num),
        }
    }
    return true, nil
}

那么我们可以这样调用:

if _, checkErr := checkNum1(9); checkErr != nil {
    fmt.Printf("检查错误信息3: errCode-> %d, errMesg-> %s\n", checkErr.Code, checkErr.Msg)
}

上面就是我们实现的一个自定义错误,在实际的开发中,特别是在框架、API开发中,我们更多的使用的是自定义错误。

在调用官方包、或者向第三方发起请求时,我们更多的使用的是官方的error

小结

本节我们讲解了Go语言中的错误处理逻辑,包括官方错误error、自定义错误等信息。

关于本节总结如下:

  • 官方错误包为error

  • error错误可以使用fmt.Errorf创建

  • error错误可以使用errors.New创建

  • 一般我们使用结构体进行自定义错误的实现

results matching ""

    No results matching ""